<?php

/**
* Image manipulation with imagemagick
* Usage
* 
* $resource = new photomanager('source.png', 'destination.png');
* // crop and resize
* $resource->resizeAndCrop(415, 233, 415, 233, 0, 0, '#333', '>', 'center');
* // create opitimized
* $resource->thumbnail(150, 150, '#333');
* // get result in variable
* $image = $resource->load();
* // delete de result
* $resource->deleteDestinationFile();
* // direct output in brower
* $resource->display();
* 
*/
class photomanager {
    private $escapeChars = null ;
    private $history = array();
    private $log = array();
    private $source = '';
    private $sourceFormat = '';
    private $destination = '';
    private $destinationFormat = '';
    private $tmpDestination = '';
    private $imageMagickPath = '';
    private $imageQuality = 90 ;
    private $transparency = false ;
    private $activePage = 0 ;
    public $debug = false;
    
	function __construct($source, $destination = '') {
        $this->source = $source ;
        $this->sourceFormat = strtolower($ext = end (explode('.', $source)));
        if ($destination == '') {
            $this->tmpDestination = sys_get_temp_dir().'/img_'.md5(uniqid(rand(), true)).'.jpg';
            $this->destinationFormat = 'jpg';
        } else {
            $this->destination = $destination;
            $this->destinationFormat = strtolower($ext = end (explode('.', $destination)));
        }
	}
	
	function __destruct() {
	    // delete tmpfile
        $this->deleteTmpFile();
	}
	
	// getters and setters
	public function getLog(){
        return $this->log;
    }
        
    public function getSourceFormat($file) {
        return $this->sourceFormat;
    }

    public function getDestinationFormat($file) {
        return $this->destinationFormat;
    }
	
	public function getBinary($binName){
        return $this->getImageMagickPath()  . $binName ;
    }
	
	function setImageMagickPath ($path){
        if($path != '')
            if ( strpos($path, '/') < strlen($path))
                $path .= '/';
        $this->imageMagickPath = str_replace(' ','\ ',$path) ;
    }

    function getImageMagickPath (){
        return $this->imageMagickPath;
    }
    
    function setSource ($path){
        $this->source = str_replace(' ','\ ',$path) ;
        return $this ;
    }

    function getSource (){
        return $this->source ;
    }
    
    function setTransparency ($transparency){
        $this->transparency = $transparency ;
        return $this ;
    }

    function getTransparency (){
        return $this->transparency ;
    }
    

    function setDestination ($path){
        $path = str_replace(' ','\ ',$path) ;
        $this->destination = $path ;
        return $this;
    }

    function getDestination (){
        if( ($this->destination == '')){
            return $this->tmpDestination;
        }
        return $this->destination ;
    }
    
    function setImageQuality($value){
        $this->imageQuality = intval($value);
        return $this;
    }

     function getImageQuality(){
        return $this->imageQuality;
    }
    
    function setActivePage($page) {
        $this->activePage = $page;
    }
        
    /**
     * execute the given command string escaped id needed
     *
     * @param string $cmd 
     * @return result
     * @author is webdesign
     */
    public function execute($cmd){
        $ret = null ;
        $out = array();

        if($this->escapeChars) {
            $cmd= str_replace    ('(','\(',$cmd);
            $cmd= str_replace    (')','\)',$cmd);
        }
        exec( $cmd .' 2>&1', $out, $ret);

        if($ret != 0)
            if($this->debug) trigger_error (new IsmImageMagickException ('Error executing "'. $cmd.'" <br>return code: '. $ret .' <br>command output :"'. implode("<br>", $out).'"' ), E_USER_NOTICE );

        $this->log[] = array(
            'cmd' => $cmd
            ,'return' => $ret
            ,'output' => $out
        );
        return $ret ;
    }
    
    /**
     * crop and resize
     *
     * @param string $output_width 
     * @param string $output_height 
     * @param string $image_width 
     * @param string $image_height 
     * @param string $offset_left 
     * @param string $offset_top 
     * @param string $background_color 
     * @param string $modifier 
     * @param string $gravity 
     * @return void
     * @author Olivier Kautz
     */
	public function resizeAndCrop(
	    $output_width, 
	    $output_height, 
	    $image_width, 
	    $image_height, 
	    $offset_left, 
	    $offset_top, 
	    $background_color = '#000', 
	    $modifier = '>^', 
	    $gravity = null
	) {
        $this->execute('\
            '.$this->getBinary('convert').'\
            -resize \''.abs(intval($image_width)).'x'.abs(intval($image_height)).$modifier.'\'\
            -extent '.abs(intval($output_width)).'x'.abs(intval($output_height))
            .($offset_left >= 0 ? '-'.abs(intval($offset_left)) : '+'.abs(intval($offset_left)))
            .($offset_top >=0 ? '-'.abs(intval($offset_top)) : '+'.abs(intval($offset_top))).'\
            -background '.( $this->getTransparency() ? 'transparent' : '\''.$background_color.'\'').'\
            -quality '.$this->getImageQuality().'\
            '.( isset($gravity) ? '-gravity '.$gravity : null).'\
            '.$this->getSource().$this->getPage().'\
            '.$this->getDestination().'\
        ');
	}
	
	/**
	 * create a thumbnail
	 *
	 * @return void
	 * @author is webdesign
	 **/
	public function thumbnail($image_width, $image_height, $background_color = '#000', $gravity = 'center') {
        $this->execute('\
            '.$this->getBinary('convert').'\
            -thumbnail \''.intval($image_width).'x'.intval($image_height).'>^\'\
            -gravity '.$gravity.'\
            -extent '.intval($image_width).'x'.intval($image_height).'\
            -background '.( $this->getTransparency() ? 'transparent' : '\''.$background_color.'\'').'\
            -quality '.$this->getImageQuality().'\
            '.$this->getSource().$this->getPage().'\
            '.$this->getDestination().'\
        ');	    
	}
	
	public function getPage() {
	    if ($this->sourceFormat == 'pdf') {
            return '['.$this->activePage.']';
	    }
    }
    
    /**
     * delete the destination file
     *
     * @return void
     * @author is webdesign
     */
    function deleteDestinationFile(){
        if (is_file($this->getDestination())) {
            unlink($this->getDestination());
        }
        
    }

    /**
     * delete tmp file
     *
     * @return void
     * @author is webdesign
     */
    function deleteTmpFile(){
        if (is_file($this->tmpDestination)) {
            unlink($this->tmpDestination);
        }
    }

    
    /**
     * return de result in a php variable
     *
     * @return bin
     * @author is webdesign
     **/
    function load() {
        if (is_file($this->getDestination())) {
            return file_get_contents($this->getDestination());
        }
    }
    
    /**
     * direct output in browser window
     *
     * @return void
     * @author is webdesign
     */   
    function display() {
        if (is_file($this->getDestination())) {
            header('Content-Type: image/'.$this->destinationFormat);
            echo $this->load();
            $this->deleteTmpFile();
            exit;
        }
    }
    
}

class IsmImageMagickException extends Exception {
    function __construct($message, $code=1){
        //parent::__construct('', $code);
        $this->message($message);
    }
    function message($message){
        echo '<br><b>IsmImageMagick</b>: ' . $message ;
    }
}

?>